package com.xhj.mybatis.datasource.unpooled;

import com.xhj.mybatis.datasource.DataSourceFactory;
import com.xhj.mybatis.reflection.MetaObject;
import com.xhj.mybatis.reflection.SystemMetaObject;

import javax.sql.DataSource;
import java.util.Properties;

/**
 * UnpooledDataSourceFactory
 *
 * @author XJks
 * @description 无池化数据源工厂
 */
public class UnpooledDataSourceFactory implements DataSourceFactory {

    /**
     * 用于保存实际的数据源对象
     */
    protected DataSource dataSource;

    public UnpooledDataSourceFactory() {
        this.dataSource = new UnpooledDataSource();
    }

    @Override
    public void setProperties(Properties props) {
        // 使用 MyBatis 的反射工具包装 dataSource，便于动态设置属性
        MetaObject metaObject = SystemMetaObject.forObject(dataSource);
        // 遍历传入的所有属性
        for (Object key : props.keySet()) {
            // 属性名
            String propertyName = (String) key;
            // 如果 dataSource 有对应的 setter 方法，则进行属性设置
            if (metaObject.hasSetter(propertyName)) {
                // 获取属性值（字符串类型）
                String value = (String) props.get(propertyName);
                // 将字符串类型的属性值转换为目标类型（int、long、boolean），否则返回原字符串
                Object convertedValue = convertValue(metaObject, propertyName, value);
                // 设置属性值
                metaObject.setValue(propertyName, convertedValue);
            }
        }
    }

    @Override
    public DataSource getDataSource() {
        return dataSource;
    }

    /**
     * 将字符串类型的属性值转换为目标类型（int、long、boolean），否则返回原字符串
     *
     * @param metaDataSource 目标数据源的 MetaObject 包装
     * @param propertyName   目标属性名
     * @param value          属性值（字符串类型）
     * @return 转换后的属性值
     */
    private Object convertValue(MetaObject metaDataSource, String propertyName, String value) {
        Object convertedValue = value;
        // 获取目标属性的类型
        Class<?> targetType = metaDataSource.getSetterType(propertyName);
        // 如果目标类型是 Integer 或 int
        if (targetType == Integer.class || targetType == int.class) {
            convertedValue = Integer.valueOf(value);
            // 如果目标类型是 Long 或 long
        } else if (targetType == Long.class || targetType == long.class) {
            convertedValue = Long.valueOf(value);
            // 如果目标类型是 Boolean 或 boolean
        } else if (targetType == Boolean.class || targetType == boolean.class) {
            convertedValue = Boolean.valueOf(value);
        }
        // 返回转换后的值
        return convertedValue;
    }

}
